﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Kira.Compiler.Bods
{
    internal class AttributeMapping : MappingBase
    {
        private static Dictionary<String, Dictionary<String, Type>> _types;

        private String _attrName;
        private AttributeMapping(String name, String attrName, Type type)
            : base(name, type)
        {
            this._attrName = attrName;
        }

        private String AttrKey
        {
            get { return this._attrName.ToUpper(); }
        }

        internal static AttributeMapping Create(String name, String attrName, Type eleType)
        {
            var instance = new AttributeMapping(name, attrName, eleType);
            if (AttributeMapping._types == null)
            {
                AttributeMapping._types = new Dictionary<String, Dictionary<String, Type>>();
            }
            if (AttributeMapping._types.ContainsKey(instance.Key))
            {
                var subTable = AttributeMapping._types[instance.Key];
                if (subTable.ContainsKey(instance.AttrKey))
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendFormat("Duplicated AttributeMapping of {0}: {1} - {2}, already mapped to {3}", instance.Key, instance.AttrKey, eleType, subTable[instance.AttrKey]);
                    throw new Exception(sb.ToString());
                }
                else
                {
                    subTable.Add(instance.AttrKey, instance.ElementType);
                }
            }
            else
            {
                var subTable = new Dictionary<String, Type>();
                subTable.Add(instance.AttrKey, instance.ElementType);
                _types.Add(instance.Key, subTable);
            }
            return instance;
        }

        internal static Type GetElementType(XElement xml)
        {
            if (_types == null)
            {
                throw new Exception("No AttributeMapping registered.");
            }
            String key = xml.GetKey();
            if (_types.ContainsKey(key))
            {
                var subTable = _types[key];
                foreach (var attr in xml.Attributes())
                {
                    String attrKey = attr.GetNameKey();
                    if (subTable.ContainsKey(attrKey))
                    {
                        return subTable[attrKey];
                    }
                }
                throw new Exception((new StringBuilder()).AppendFormat("No attribute matched for AttributeMapping {0}.", key).ToString());
            }
            else
            {
                throw new Exception((new StringBuilder()).AppendFormat("No AttributeMapping found for {0}.", key).ToString());
            }
        }

    }
}
